{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7dc17cfc3c127df5",
   "metadata": {
    "collapsed": false,
    "id": "7dc17cfc3c127df5"
   },
   "source": [
    "<a href=\"https://colab.research.google.com/github/milvus-io/bootcamp/blob/master/bootcamp/tutorials/integration/quickstart_mem0_with_milvus.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>   <a href=\"https://github.com/milvus-io/bootcamp/blob/master/bootcamp/tutorials/integration/quickstart_mem0_with_milvus.ipynb\" target=\"_blank\">\n",
    "    <img src=\"https://img.shields.io/badge/View%20on%20GitHub-555555?style=flat&logo=github&logoColor=white\" alt=\"GitHub Repository\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8b5689b0c2dd927e",
   "metadata": {
    "collapsed": false,
    "id": "8b5689b0c2dd927e"
   },
   "source": [
    "# Getting Started with Mem0 and Milvus\n",
    "\n",
    "\n",
    "[Mem0](https://mem0.ai/) is an intelligent memory layer for AI applications, designed to deliver personalized and efficient interactions by retaining user preferences and continuously adapting over time. Ideal for chatbots and AI-driven tools, Mem0 creates seamless, context-aware experiences.\n",
    "\n",
    "In this tutorial, we’ll cover essential Mem0 memory management operations—adding, retrieving, updating, searching, deleting, and tracking memory history—using [Milvus](https://milvus.io/), a high-performance, open-source vector database that powers efficient storage and retrieval. This hands-on introduction will guide you through foundational memory operations to help you build personalized AI interactions with Mem0 and Milvus.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "809928fa52f191c9",
   "metadata": {
    "collapsed": false,
    "id": "809928fa52f191c9"
   },
   "source": [
    "## Preparation\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2La6P9TMV7ZM",
   "metadata": {
    "id": "2La6P9TMV7ZM"
   },
   "source": [
    "### Download required libraries\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4c7accf1b9622209",
   "metadata": {
    "id": "4c7accf1b9622209"
   },
   "outputs": [],
   "source": [
    "! pip install mem0ai pymilvus"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "KlXjMyvIaO9x",
   "metadata": {
    "id": "KlXjMyvIaO9x"
   },
   "source": [
    "> If you are using Google Colab, to enable dependencies just installed, you may need to **restart the runtime** (click on the \"Runtime\" menu at the top of the screen, and select \"Restart session\" from the dropdown menu)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "hEPGSpquauA7",
   "metadata": {
    "id": "hEPGSpquauA7"
   },
   "source": [
    "### Configure Mem0 with Milvus\n",
    "\n",
    "We will use OpenAI as the LLM in this example. You should prepare the [api key](https://platform.openai.com/docs/quickstart) `OPENAI_API_KEY` as an environment variable.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "PCNwsKv-UT6j",
   "metadata": {
    "id": "PCNwsKv-UT6j"
   },
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "os.environ[\"OPENAI_API_KEY\"] = \"sk-***********\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "sb2JuvTSUtZh",
   "metadata": {
    "id": "sb2JuvTSUtZh"
   },
   "source": [
    "Now, we can configure Mem0 to use Milvus as the vector store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ul65iMC0Uzmz",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "ul65iMC0Uzmz",
    "outputId": "2a16df5e-1c99-42c8-ffb9-709b2923bd53"
   },
   "outputs": [],
   "source": [
    "# Define Config\n",
    "from mem0 import Memory\n",
    "\n",
    "config = {\n",
    "    \"vector_store\": {\n",
    "        \"provider\": \"milvus\",\n",
    "        \"config\": {\n",
    "            \"collection_name\": \"quickstart_mem0_with_milvus\",\n",
    "            \"embedding_model_dims\": \"1536\",\n",
    "            \"url\": \"./milvus.db\",  # Use local vector database for demo purpose\n",
    "        },\n",
    "    },\n",
    "    \"version\": \"v1.1\",\n",
    "}\n",
    "\n",
    "m = Memory.from_config(config)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "h5y7B2QBVV7V",
   "metadata": {
    "id": "h5y7B2QBVV7V"
   },
   "source": [
    "> - If you only need a local vector database for small scale data or prototyping, setting the uri as a local file, e.g.`./milvus.db`, is the most convenient method, as it automatically utilizes [Milvus Lite](https://milvus.io/docs/milvus_lite.md) to store all data in this file.\n",
    "> - If you have large scale of data, say more than a million vectors, you can set up a more performant Milvus server on [Docker or Kubernetes](https://milvus.io/docs/quickstart.md). In this setup, please use the server address and port as your uri, e.g.`http://localhost:19530`. If you enable the authentication feature on Milvus, use \"<your_username>:<your_password>\" as the token, otherwise don't set the token.\n",
    "> - If you use [Zilliz Cloud](https://zilliz.com/cloud), the fully managed cloud service for Milvus, adjust the `uri` and `token`, which correspond to the [Public Endpoint and API key](https://docs.zilliz.com/docs/on-zilliz-cloud-console#cluster-details) in Zilliz Cloud."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "q7eGl6tKVoCp",
   "metadata": {
    "id": "q7eGl6tKVoCp"
   },
   "source": [
    "## Managing User Memories with Mem0 and Milvus\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dFBywoCDWMOD",
   "metadata": {
    "id": "dFBywoCDWMOD"
   },
   "source": [
    "### Adding a Memory\n",
    "The `add` function stores unstructured text in Milvus as a memory, associating it with a specific user and optional metadata.\n",
    "\n",
    "Here, we're adding Alice's memory, \"working on improving my tennis skills,\" along with relevant metadata for context to Milvus."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "TJg6QewOWZE_",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "TJg6QewOWZE_",
    "outputId": "916c3723-ce7c-4b67-f274-134c271b268f"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'results': [{'id': '77162018-663b-4dfa-88b1-4f029d6136ab',\n",
       "   'memory': 'Working on improving tennis skills',\n",
       "   'event': 'ADD'}],\n",
       " 'relations': []}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Add a memory to user: Working on improving tennis skills\n",
    "res = m.add(\n",
    "    messages=\"I am working on improving my tennis skills.\",\n",
    "    user_id=\"alice\",\n",
    "    metadata={\"category\": \"hobbies\"},\n",
    ")\n",
    "\n",
    "res"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eaiKUf5MZs0p",
   "metadata": {
    "id": "eaiKUf5MZs0p"
   },
   "source": [
    "### Update a Memory"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "pkM5MolHYhfm",
   "metadata": {
    "id": "pkM5MolHYhfm"
   },
   "source": [
    "We can use the `add` function's return value to retrieve the memory ID, allowing us to update this memory with new information via `update`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "s9gUfYvQYg-K",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "s9gUfYvQYg-K",
    "outputId": "2d464c53-f5f0-4f29-f069-223af24bf320"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'message': 'Memory updated successfully!'}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Get memory_id\n",
    "memory_id = res[\"results\"][0][\"id\"]\n",
    "\n",
    "# Update this memory with new information: Likes to play tennis on weekends\n",
    "m.update(memory_id=memory_id, data=\"Likes to play tennis on weekends\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "Rkj0CkZsZyFV",
   "metadata": {
    "id": "Rkj0CkZsZyFV"
   },
   "source": [
    "### Get All Memory For a User"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "LLlgCNJnW1eV",
   "metadata": {
    "id": "LLlgCNJnW1eV"
   },
   "source": [
    "We can use the `get_all` function to view all inserted memories or filter by `user_id` in Milvus.\n",
    "\n",
    "Note that we can see the memory is now changed from \"Working on impriving tennis skills\" to \"Likes to play tennis on weekends\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "getEKekmXiuu",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "getEKekmXiuu",
    "outputId": "53a1a9b7-67db-40ff-a314-adb29b4f426a"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'results': [{'id': '77162018-663b-4dfa-88b1-4f029d6136ab',\n",
       "   'memory': 'Likes to play tennis on weekends',\n",
       "   'hash': '4c3bc9f87b78418f19df6407bc86e006',\n",
       "   'metadata': None,\n",
       "   'created_at': '2024-11-01T19:33:44.116920-07:00',\n",
       "   'updated_at': '2024-11-01T19:33:47.619857-07:00',\n",
       "   'user_id': 'alice'}]}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Get all memory for the user Alice\n",
    "m.get_all(user_id=\"alice\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "xcv5q2hUaLGx",
   "metadata": {
    "id": "xcv5q2hUaLGx"
   },
   "source": [
    "### View Memory Update History"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3U6MZBCdZpln",
   "metadata": {
    "id": "3U6MZBCdZpln"
   },
   "source": [
    "We can also view the memory update history by specifying which memory_id we are interested in via `history` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9PQZuH7XZiED",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "9PQZuH7XZiED",
    "outputId": "d373faaf-8254-4a99-cd12-203b9e37f36f"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'id': '71ed3cec-5d9a-4fa6-a009-59802450c0b9',\n",
       "  'memory_id': '77162018-663b-4dfa-88b1-4f029d6136ab',\n",
       "  'old_memory': None,\n",
       "  'new_memory': 'Working on improving tennis skills',\n",
       "  'event': 'ADD',\n",
       "  'created_at': '2024-11-01T19:33:44.116920-07:00',\n",
       "  'updated_at': None},\n",
       " {'id': 'db2b003c-ffb7-42e4-bd8a-b9cf56a02bb9',\n",
       "  'memory_id': '77162018-663b-4dfa-88b1-4f029d6136ab',\n",
       "  'old_memory': 'Working on improving tennis skills',\n",
       "  'new_memory': 'Likes to play tennis on weekends',\n",
       "  'event': 'UPDATE',\n",
       "  'created_at': '2024-11-01T19:33:44.116920-07:00',\n",
       "  'updated_at': '2024-11-01T19:33:47.619857-07:00'}]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.history(memory_id=memory_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "EpqA0LH3a99l",
   "metadata": {
    "id": "EpqA0LH3a99l"
   },
   "source": [
    "### Search Memory"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "XLQNqROWbCVH",
   "metadata": {
    "id": "XLQNqROWbCVH"
   },
   "source": [
    "We can use `search` function to look for the most related memory for the user.\n",
    "\n",
    "Let's start by adding another memory for Alice."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "PNM1M-kLbTUs",
   "metadata": {
    "id": "PNM1M-kLbTUs"
   },
   "outputs": [],
   "source": [
    "new_mem = m.add(\n",
    "    \"I have a linear algebra midterm exam on November 20\",\n",
    "    user_id=\"alice\",\n",
    "    metadata={\"category\": \"task\"},\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "IlrvNxhfbZ_6",
   "metadata": {
    "id": "IlrvNxhfbZ_6"
   },
   "source": [
    "Now, we call `get_all` specifying the user_id to verify that we have indeed 2 memory entries for user Alice."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "gZoe1kZubYqG",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "gZoe1kZubYqG",
    "outputId": "d941bf04-0ffb-4786-c6c1-371df6f918b5"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'results': [{'id': '77162018-663b-4dfa-88b1-4f029d6136ab',\n",
       "   'memory': 'Likes to play tennis on weekends',\n",
       "   'hash': '4c3bc9f87b78418f19df6407bc86e006',\n",
       "   'metadata': None,\n",
       "   'created_at': '2024-11-01T19:33:44.116920-07:00',\n",
       "   'updated_at': '2024-11-01T19:33:47.619857-07:00',\n",
       "   'user_id': 'alice'},\n",
       "  {'id': 'aa8eaa38-74d6-4b58-8207-b881d6d93d02',\n",
       "   'memory': 'Has a linear algebra midterm exam on November 20',\n",
       "   'hash': '575182f46965111ca0a8279c44920ea2',\n",
       "   'metadata': {'category': 'task'},\n",
       "   'created_at': '2024-11-01T19:33:57.271657-07:00',\n",
       "   'updated_at': None,\n",
       "   'user_id': 'alice'}]}"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.get_all(user_id=\"alice\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "nyg64688bSll",
   "metadata": {
    "id": "nyg64688bSll"
   },
   "source": [
    "We can perform `search` now by providing `query` and `user_id`. Note that we are by default using `L2` metric for similarity search, so a smaller `score` means greater similarity."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "-rtZHl3UcEFC",
   "metadata": {
    "id": "-rtZHl3UcEFC"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'results': [{'id': '77162018-663b-4dfa-88b1-4f029d6136ab',\n",
       "   'memory': 'Likes to play tennis on weekends',\n",
       "   'hash': '4c3bc9f87b78418f19df6407bc86e006',\n",
       "   'metadata': None,\n",
       "   'score': 1.2807445526123047,\n",
       "   'created_at': '2024-11-01T19:33:44.116920-07:00',\n",
       "   'updated_at': '2024-11-01T19:33:47.619857-07:00',\n",
       "   'user_id': 'alice'},\n",
       "  {'id': 'aa8eaa38-74d6-4b58-8207-b881d6d93d02',\n",
       "   'memory': 'Has a linear algebra midterm exam on November 20',\n",
       "   'hash': '575182f46965111ca0a8279c44920ea2',\n",
       "   'metadata': {'category': 'task'},\n",
       "   'score': 1.728922724723816,\n",
       "   'created_at': '2024-11-01T19:33:57.271657-07:00',\n",
       "   'updated_at': None,\n",
       "   'user_id': 'alice'}]}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.search(query=\"What are Alice's hobbies\", user_id=\"alice\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "lh9OCFswfyL9",
   "metadata": {
    "id": "lh9OCFswfyL9"
   },
   "source": [
    "### Delete Memory"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "JmF_2F0_f0Nq",
   "metadata": {
    "id": "JmF_2F0_f0Nq"
   },
   "source": [
    "We can also `delete` a memory by providing the corresponding `memory_id`.\n",
    "\n",
    "We will delete the memory \"Likes to play tennis on weekends\" as its `memory_id` has already been retrieved, and call `get_all` to verify the deletion is successful."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "31JVJryEgL5B",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "31JVJryEgL5B",
    "outputId": "0b1370cb-e761-4823-ec53-b3798d728dd5"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'results': [{'id': 'aa8eaa38-74d6-4b58-8207-b881d6d93d02',\n",
       "   'memory': 'Has a linear algebra midterm exam on November 20',\n",
       "   'hash': '575182f46965111ca0a8279c44920ea2',\n",
       "   'metadata': {'category': 'task'},\n",
       "   'created_at': '2024-11-01T19:33:57.271657-07:00',\n",
       "   'updated_at': None,\n",
       "   'user_id': 'alice'}]}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.delete(memory_id=memory_id)\n",
    "\n",
    "m.get_all(\"alice\")"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
